/// ShaderManager.cpp
/// Matthew DiBernardo (Cryptex)
/// 07.28.09
///
/// See ShaderManager.h for usage information.

#include "ShaderManager.h"

ShaderManager& ShaderManager::Instance(void)
{
	static ShaderManager _instance;
	return _instance;
}

void ShaderManager::Clear(void)
{
	for(std::map<unsigned int, Shader*>::iterator i = shaderMap.begin();
		i != shaderMap.end(); ++i)
	{
		if(i->second != NULL)
			delete i->second;
	}

	shaderMap.clear();
	nameMap.clear();
}

void ShaderManager::ReleaseAllShaders(void)
{
	shaderFac.DisableCGProfiles();
	glUseProgram(NULL);
}

unsigned int ShaderManager::MakeNewID(void)
{
	if(m_lastID == 0) ++m_lastID; // Valid ID's must be non-zero
	if(m_lastID > SM_MAXSHADERS) m_lastID = 1;

	unsigned int startID = m_lastID;
	bool hasLooped = false;

	while(shaderMap.count(m_lastID)) // Will return non-zero if ID is in use
	{
		if(m_lastID > SM_MAXSHADERS)
		{
			m_lastID = 1;
			hasLooped = true;
		}
		if(m_lastID == startID && hasLooped)
			return 0; // No available indexes at this time
		m_lastID++; // Increment the ID
	}
	return m_lastID;
}

unsigned int ShaderManager::GetID(std::string fileName)
{
	if(nameMap.count(fileName) == 0)
	{
		unsigned int newID = MakeNewID();
		Shader* newSh = shaderFac.LoadShader(fileName);
		if(!newSh)
			return 0;

		nameMap[fileName] = newID;
		shaderMap[newID] = newSh;

		return newID;
	}
	return nameMap[fileName];
}

/*** DEPRECATED UNTIL FURTHER NOTICE ***
std::string ShaderManager::GetFileName(unsigned int shaderID)
{
	if(nameMap.count(shaderID) == 0)
		return "";
	return nameMap[shaderID];
}
***									***/

Shader* ShaderManager::GetShader(unsigned int shaderID)
{
	if(shaderMap.count(shaderID) == 0)
		return NULL;
	return shaderMap[shaderID];
}

Shader* ShaderManager::GetShader(std::string fileName)
{
	return GetShader(GetID(fileName));
}